package com.fire.market.manager;

import com.fire.component.cache.local.LocalCacheOperate;
import com.fire.component.cache.local.RedisOperate;
import com.fire.component.extension.Assert;
import com.fire.component.extension.BizCommonError;
import com.fire.component.extension.ExceptionFactory;
import com.fire.market.promo.api.dto.PromoInfo;
import com.fire.market.entity.ItemDo;
import com.fire.market.entity.ItemStockDo;
import com.fire.market.integration.service.PromoIntegrationService;
import com.fire.market.model.ItemModel;
import com.fire.market.product.api.dto.ItemInfo;
import com.fire.market.repository.ItemRepository;
import com.fire.market.repository.ItemStockRepository;
import org.springframework.beans.BeanUtils;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

@Component
public class ItemManager {
    @Resource
    private ItemRepository itemRepository;
    @Resource
    private ItemStockRepository itemStockRepository;
    @Resource
    private PromoIntegrationService promoIntegrationService;
    @Resource
    private RedisTemplate redisTemplate;
    
    public List<ItemInfo> selectAllItem() {
        List<ItemDo> itemDoList = itemRepository.selectAllItem();
        List<ItemInfo> itemInfoList = itemDoList.stream().map(itemDo -> {
            ItemInfo ItemInfo = new ItemInfo();
            BeanUtils.copyProperties(itemDo, ItemInfo);
            ItemInfo.setPrice(BigDecimal.valueOf(itemDo.getPrice()));
            ItemStockDo itemStockDo = itemStockRepository.selectItemStockById(itemDo.getId());
            ItemInfo.setStock(itemStockDo.getStock());
            return ItemInfo;
        }).collect(Collectors.toList());
        return itemInfoList;
    }

    public ItemInfo createItem(ItemModel itemModel) {
        Assert.notNull(itemModel,"itemModel is null");
//        ValidationResult validate = validator.validate(itemModel);
//        if (validate.isHasErrors()){
//            throw new BusinessException(EmBusinessError.PARAMETER_VALIDATION_ERROR,validate.getErrMsg());
//        }
        //保存商品
        ItemDo itemDo = new ItemDo();
        BeanUtils.copyProperties(itemModel, itemDo);
        //itemDo中的price为double的而为了不损失精度，itemModel中的price为BigDecimal类型不同，需要单独设置
        itemDo.setPrice(itemModel.getPrice().doubleValue());
        itemRepository.insertItem(itemDo);

        //保存商品库存
        ItemStockDo itemStockDo = new ItemStockDo();
        itemStockDo.setStock(itemModel.getStock());
        itemStockDo.setItemId(itemDo.getId());
        itemStockRepository.insertItemStock(itemStockDo);

        //回调
        ItemInfo itemInfo = this.selectItemById(itemDo.getId());
        if (itemInfo == null){
            throw ExceptionFactory.bizException(BizCommonError.UNKNOWN_ERROR.getErrCode(), "添加商品失败");
        }
        return itemInfo;
    }

    public ItemInfo selectItemById(Integer id) {
        Assert.notNull(id, "id is null");
        //本地热点缓存
        ItemInfo localItemInfoCache = LocalCacheOperate.getFromCommonCache("item_" + id, ItemInfo.class);
        if (localItemInfoCache != null){
            return localItemInfoCache;
        }
        //读redis集中式缓存
        ItemInfo redisItemInfoCache = (ItemInfo) redisTemplate.opsForValue().get("item_" + id);
        if (redisItemInfoCache != null){
            //填充本地缓存
            LocalCacheOperate.setCommonCache("item_" + id,redisItemInfoCache);
            return redisItemInfoCache;
        }
        ItemDo itemDo = itemRepository.selectItemById(id);
        if (itemDo == null) return null;
        ItemStockDo itemStockDo = itemStockRepository.selectItemStockById(itemDo.getId());
        if (itemStockDo == null) return null;
        ItemModel itemModel = new ItemModel();
        BeanUtils.copyProperties(itemDo, itemModel);
        itemModel.setPrice(BigDecimal.valueOf(itemDo.getPrice()));
        itemModel.setStock(itemStockDo.getStock());
        ItemInfo itemInfo = new ItemInfo();
        BeanUtils.copyProperties(itemModel, itemInfo);
        //获取秒杀活动的商品信息
        PromoInfo promoInfo = promoIntegrationService.queryPromoByItemId(id);
        if (promoInfo != null){
            itemInfo.setStatus(promoInfo.getStatus());
            itemInfo.setPromoName(promoInfo.getPromoName());
            itemInfo.setStartDate(promoInfo.getStartDate());
            itemInfo.setEndDate(promoInfo.getEndDate());
            itemInfo.setPromoItemPrice(promoInfo.getPromoItemPrice());
            itemInfo.setPromoId(promoInfo.getId());
        }else{
            itemInfo.setStatus(0);
        }

        //填充本地缓存
        LocalCacheOperate.setCommonCache("item_" + id,itemInfo);
        //写redis集中式缓存
        RedisOperate.set("item_" + id, itemInfo,10, TimeUnit.MINUTES);
        return itemInfo;
    }

    public boolean decreaseStock(Integer itemId, Integer amount) {
        Assert.notNull(itemId, "itemId is null");
        Assert.notNull(amount, "amount is null");
        return itemStockRepository.decreaseStock(itemId, amount);
    }

    public void increaseSales(Integer itemId, Integer amount) {
        Assert.notNull(itemId, "itemId is null");
        Assert.notNull(amount, "amount is null");
        itemRepository.increaseSales(itemId, amount);
    }

    public void decreaseSales(Integer itemId, Integer amount) {
        Assert.notNull(itemId, "itemId is null");
        Assert.notNull(amount, "amount is null");
        itemRepository.decreaseSales(itemId,amount);
    }
}
